package work.jame.blog.framework.limit.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import work.jame.blog.configuration.security.LoginUser;
import work.jame.blog.framework.limit.AbstractRequestLimitHandler;
import work.jame.blog.framework.utils.http.IpUtils;
import work.jame.blog.framework.utils.redis.RedisService;
import work.jame.blog.framework.utils.redis.RedisUtils;
import work.jame.blog.framework.utils.security.SpringSecurityUtils;
import work.jame.blog.service.WhiteListService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 白名单请求处理器
 *
 * @author : Jame
 * @date : 2023-05-13 14:24
 **/
@Component
public class WhiteListRequestLimitHandler extends AbstractRequestLimitHandler {

    @Autowired
    private RedisService redisService;

    @Autowired
    private WhiteListService whiteListService;


    @Override
    public Operation handler(HttpServletRequest request, HttpServletResponse response) {
        String ip = IpUtils.getIpAddr(request);
        String whiteListIpKey = RedisUtils.getWhiteListIpKey(ip);

        //首先根据ip查询是否存在白名单中
        if (redisService.hasKey(whiteListIpKey)) {
            boolean allowByIp = redisService.getCacheObject(whiteListIpKey);
            if (allowByIp) {
                return Operation.SKIP;
            }
        } else {
            //如果缓存中没有则去查询数据库
            //无论是否存在都添加到缓存
            if (whiteListService.queryWhiteListExistByIp(ip)) {
                redisService.setCacheObject(whiteListIpKey, true);
                return Operation.SKIP;
            } else {
                redisService.setCacheObject(whiteListIpKey, false);
            }
        }

        //然后再根据用户id查询
        LoginUser loginUser;
        try {
            loginUser = SpringSecurityUtils.getCurrentLoginUserInfo();
        } catch (Exception e) {
            //忽略错误-一些不需要登录就可以请求的接口
            return Operation.ALLOW;
        }
        Long userId = loginUser.getUser().getId();
        String userIdKey = RedisUtils.getWhiteListUserIdKey(userId);
        //先根据ip查询是否存在白名单中
        if (redisService.hasKey(userIdKey)) {
            boolean allowByUserId = redisService.getCacheObject(userIdKey);
            if (allowByUserId) {
                return Operation.SKIP;
            }
        } else {
            //如果缓存中没有则去查询数据库
            //无论是否存在都添加到缓存
            if (whiteListService.queryWhiteListExistByUserId(userId)) {
                redisService.setCacheObject(userIdKey, true);
                return Operation.SKIP;
            } else {
                redisService.setCacheObject(userIdKey, false);
            }
        }
        return Operation.ALLOW;
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE;
    }
}
